package run.siyuan.manag.controller;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.kaptcha.Kaptcha;
import com.baomidou.kaptcha.exception.KaptchaIncorrectException;
import com.baomidou.kaptcha.exception.KaptchaNotFoundException;
import com.baomidou.kaptcha.exception.KaptchaRenderException;
import com.baomidou.kaptcha.exception.KaptchaTimeoutException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.web.bind.annotation.*;
import run.siyuan.common.constant.Constant;
import run.siyuan.common.entity.Result;
import run.siyuan.common.exception.ExceptionProperties;
import run.siyuan.common.util.RedisUtil;
import run.siyuan.manag.annotation.OperLog;
import run.siyuan.manag.entity.LoginBean;
import run.siyuan.manag.entity.SysUser;
import run.siyuan.manag.security.JwtAuthenticationToken;
import run.siyuan.manag.service.SysUserService;
import run.siyuan.manag.util.SecurityUtil;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;

/**
 * @program: sy-auth-manag
 * @description: 登入
 * @author: SY
 * @create: 2021-01-14 11:09
 **/
@Api(tags = "登入相关")
@Slf4j
@RestController
public class SysLoginController {

    @Autowired
    private Producer producer;
    @Autowired
    private ExceptionProperties properties;
    @Autowired
    private SysUserService userService;
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private RedisUtil redisUtil;

    private static final Integer IMG_CODE_EXPIRE = 60 * 3;


    /**
     * FIXME 将验证码存入 session 并且指定一个值。改造：应存放在 redis，以 IP 为 key
     *
     * @param captchaKey
     * @param response
     */
    @OperLog(description = "获取图形验证码")
    @GetMapping("/render")
    @ApiOperation(value = "获取图形验证码", notes = "图形验证")
    public void render(@RequestParam("captchaKey") String captchaKey, HttpServletResponse response) {
        try {
            String imgCode = producer.createText();
            log.info("图形验证码为:{} captchaKey:{}", imgCode, captchaKey);
            redisUtil.set(captchaKey, imgCode, IMG_CODE_EXPIRE);
            BufferedImage image = producer.createImage(imgCode);
            response.setHeader("Cache-Control", "no-store, no-cache");
            response.setContentType("image/jpeg");
            ServletOutputStream outputStream = response.getOutputStream();
            ImageIO.write(image, "jpg", outputStream);
            IOUtils.closeQuietly(outputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * FIXME 验证码应从 redis 获取
     *
     * @param loginBean
     * @param request
     * @return
     */
    @OperLog(description = "登入")
    @ApiOperation("登入")
    @PostMapping("/login")
    public Result login(@RequestBody LoginBean loginBean, HttpServletRequest request) {
        try {
            String username = loginBean.getUsername();
            String password = loginBean.getPassword();
            String captcha = loginBean.getCaptcha();
            String captchaKey = loginBean.getCaptchaKey();
            Object captchaValue = redisUtil.get(captchaKey);
            if (ObjectUtil.isEmpty(captchaValue)) {
                return Result.error(50003, properties.getCodeName("50003"));
            }
            log.info("图形验证码:{},输入验证码:{}", captcha.toString(), captcha);
            if (!captchaValue.equals(captcha)) {
                return Result.error(50002, properties.getCodeName("50002"));
            }
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("name", username);
            SysUser user = userService.getOne(queryWrapper);
            if (ObjectUtil.isEmpty(user)) {
                return Result.error(50006, properties.getCodeName("50006"));
            }
            if (user.getStatus().equals(Constant.ACCOUNT_STATUS_DISABLE)) {
                return Result.error(50007, properties.getCodeName("50007"));
            }
            JwtAuthenticationToken token = SecurityUtil.login(request, username, password, authenticationManager);
            return Result.success().data(token);
        } catch (Exception e) {
            log.info("登入失败:{}", e.getMessage());
            return Result.error(50008, e.getMessage());
        }
    }

}